package com.msmall.community.bbs.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.msmall.base.cache.CacheFactory;
import com.msmall.base.exception.AuthorityException;
import com.msmall.base.exception.DataNotFoundException;
import com.msmall.base.pager.PaginationSupport;
import com.msmall.base.service.impl.BaseManagerImpl;
import com.msmall.base.util.ConstantDB;
import com.msmall.base.util.Constants;
import com.msmall.base.util.DateUtil;
import com.msmall.community.bbs.dao.TopicDao;
import com.msmall.community.bbs.model.Master;
import com.msmall.community.bbs.model.Thread;
import com.msmall.community.bbs.model.Topic;
import com.msmall.community.bbs.service.MasterManager;
import com.msmall.community.bbs.service.TopicManager;
import com.msmall.community.bbs.util.BbsUtil;
import com.msmall.community.common.util.ContentUtil;
import com.msmall.community.common.util.FilterCharsUtil;
import com.msmall.community.score.service.ScoreManager;
import com.msmall.community.user.model.UserInfo;
import com.msmall.community.user.service.UserManager;


public class TopicManagerImpl extends BaseManagerImpl<Topic, Long> implements TopicManager{

	private static final Log logger = LogFactory.getLog(TopicManagerImpl.class);
	
	private TopicDao topicDao;
	
	private MasterManager masterManager;
	
	private ScoreManager scoreManager;
	
	private UserManager userManager;
	
	public void setMasterManager(MasterManager masterManager) {
		this.masterManager = masterManager;
	}
	public void setScoreManager(ScoreManager scoreManager) {
		this.scoreManager = scoreManager;
	}
	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}
	public void setTopicDao(TopicDao topicDao) {
		this.topicDao = topicDao;
	}
	
	public Topic saveTopic(Topic topic, Long boardId, Long userid, String userAgentType) {
		UserInfo user = userManager.getByUserid(userid);
		Date date = new Date();
		String content = topic.getContent();
		String[] urls = new String[]{};
		try {
			urls = BbsUtil.writeForumFile(content, boardId, date, userAgentType);
		} catch (IOException e) {
			logger.error(e.getStackTrace());
		}
		
		if(StringUtils.isEmpty(topic.getContentAbstract())){
			int size = BbsUtil.getContentAbstractChars();
			content = ContentUtil.escapeHtmlTags(content);
			if(content.length() > size){
				topic.setContentAbstract(content.substring(0, size));
			}else{
				topic.setContentAbstract(content);
			}
		}
		
		topic.setFilePath(urls[0]);
		topic.setFileName(urls[1]);
		topic.setFileExt(urls[2]);
		topic.setFileFlag(Constants.USER_AGENT_TYPE_HTML.equals(userAgentType)?Constants.FILE_CREATED_FLAG_HTML:Constants.FILE_CREATED_FLAG_WML);
		
		topic.setBoardid(boardId);
		topic.setUserid(userid);
		topic.setNickname(user.getNickname());
		topic.setCreateTime(date);
		topic.setLastModifyTime(date);
		topic.setLastThreadTime(date);
		topic.setClassRuleId(null);
		topic.setClickAmount(0);
		topic.setElite(ConstantDB.UNELITE);
		topic.setEnabled(ConstantDB.AVALIABLE);
		topic.setNotice(ConstantDB.NOTICE);
		topic.setReply(ConstantDB.REPLY);
	//	topic.setSignature(signature);
		topic.setSource(Constants.USER_AGENT_TYPE_WML.equalsIgnoreCase(userAgentType)? ConstantDB.USER_AGENT_TYPE_WML :ConstantDB.USER_AGENT_TYPE_HTML);
		topic.setThreadAmount(0);
		topic.setTop(ConstantDB.UNTOP);
		
		topic = topicDao.save(topic);
		
		scoreManager.addTopic(userid, false);
		userManager.addTopicAmount(userid);
		return topic;
	}
	/**
	 * 此方法保存的TOPIC 不能访问 enabled = constantdb.unavaliable
	 * 目前只有创建TeamTopic时使用
	 */
	public Topic saveTopicDisabled(Topic topic, Long boardId, Long userid, String userAgentType) {
		UserInfo user = userManager.getByUserid(userid);
		Date date = new Date();
		String content = topic.getContent();
		String[] urls = new String[]{};
		try {
			urls = BbsUtil.writeForumFile(content, boardId, date, userAgentType);
		} catch (IOException e) {
			logger.error(e.getStackTrace());
		}
		topic.setFilePath(urls[0]);
		topic.setFileName(urls[1]);
		topic.setFileExt(urls[2]);
		topic.setFileFlag(Constants.USER_AGENT_TYPE_HTML.equals(userAgentType)?Constants.FILE_CREATED_FLAG_HTML:Constants.FILE_CREATED_FLAG_WML);
		
		topic.setBoardid(boardId);
		topic.setUserid(userid);
		topic.setNickname(user.getNickname());
		topic.setCreateTime(date);
		topic.setLastModifyTime(date);
		topic.setLastThreadTime(date);
		topic.setClassRuleId(null);
		topic.setClickAmount(0);
		topic.setElite(ConstantDB.UNELITE);
		topic.setEnabled(ConstantDB.UNAVALIABLE);
		topic.setNotice(ConstantDB.NOTICE);
		topic.setReply(ConstantDB.REPLY);
	//	topic.setSignature(signature);
		topic.setSource(Constants.USER_AGENT_TYPE_WML.equalsIgnoreCase(userAgentType)? ConstantDB.USER_AGENT_TYPE_WML :ConstantDB.USER_AGENT_TYPE_HTML);
		topic.setThreadAmount(0);
		topic.setTop(ConstantDB.UNTOP);
		
		topic = topicDao.save(topic);
		
		scoreManager.addTopic(userid, false);
		userManager.addTopicAmount(userid);
		return topic;
	}
	
	public void getThreadPaginationByTopic(PaginationSupport page, Long userid, Long topicId, Long who) {
		page.setClazz(Thread.class);
		
		String queryString = "SELECT t from Thread t, Topic p where p.topicId = " + topicId + " and p.topicId=t.topicid";
		if(who != null && who != 0){
			queryString += " and t.userid="+who;
		}
		queryString += " order by t.createTime asc";
		page.setQueryString(queryString);
		topicDao.getPagination(page);
		
	}
	public void addClickAmount(Long topicId) {
		addClickAmount((Topic)get(Topic.class, topicId));
	}
	public void addClickAmount(Topic topic) {
		topic.setClickAmount(topic.getClickAmount() + 1);
		topicDao.save(topic);
	}

	public void setElite(Long topicId, Long userid) throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setElite(ConstantDB.ELITE);
					topic.setTop(ConstantDB.UNTOP);
					topic.setCommend(ConstantDB.UNCOMMEND);
					topicDao.save(topic);
					userManager.addEliteAmount(topic.getUserid());
					scoreManager.addTopicElite(topic.getUserid(),true);
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not set " + topicId + " elite");
		}
	}
	public void setTop(Long topicId, Long userid) throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setTop(ConstantDB.TOP);
					topic.setElite(ConstantDB.UNELITE);
					topic.setCommend(ConstantDB.UNCOMMEND);
					topicDao.save(topic);
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not set " + topicId + " top");
		}
	}
	public List<Thread> viewUserOnly(Long topicId, Long userid) {
		// TODO Auto-generated method stub
		return null;
	}
	// 只显示有效的帖子
	public void getPaginationbyUserid(PaginationSupport page, Long userid) {
		page.setClazz(Topic.class);
		String queryString = " from Topic t where t.userid=" + userid + " and t.enabled=1 order by t.topicId DESC";
		page.setQueryString(queryString);
		topicDao.getPagination(page);
	}
	
	
	public void delete(Long topicId,Long userid) throws AuthorityException {

		Topic topic = topicDao.get(topicId);
		boolean tag = false; //标志vusername是否有权限删除vtopicid
		try { // 判断是否是版主删除帖子
			List list = masterManager.getMastersByBoardId(topic.getBoardid());
			Iterator it = list.iterator();
			while(it.hasNext()){
				Master master = (Master) it.next();
				if(userid.compareTo(master.getUserid()) == 0){
					tag = true;
					break;
				}
			}
		} catch (DataNotFoundException e) {
		}
		if(tag == false){ // 判断是否是发帖人删除帖子
			if(userid.compareTo(topic.getUserid()) == 0){
				tag = true;
			}
		}else{
		}
		if(!tag){
			throw new AuthorityException("user : " + userid + " don't have enouth authority to delete topic :" + topic.getTopicId());
		}
		
		topic.setEnabled(ConstantDB.UNAVALIABLE);
		scoreManager.reduceTopic(topic.getUserid(),true);
		topicDao.save(topic);
	}
	public Topic getTopic(Long topicId) throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		return topic;
	}
	public void updateTopic(Topic topic, Long userid, String uat) throws DataNotFoundException, AuthorityException {
		Topic sample = topicDao.get(topic.getTopicId());
		if(userid.compareTo(sample.getUserid()) != 0){
			logger.error("user : " + userid + " don't have enouth authority to update topic :" + topic.getTopicId());
			throw new AuthorityException("user : " + userid + " don't have enouth authority to update topic :" + topic.getTopicId());
		}
		String title = topic.getTitle();
		int titleOK = BbsUtil.checkTopicTitleLength(title);
		if(titleOK == 1){
			return;
		}
		if(titleOK == 2){
			return;
		}
		boolean titleC = FilterCharsUtil.containsFilterChars(title);
		if(titleC){
			return;
		}
		
		String content = topic.getContent();
		int contentOK = BbsUtil.checkTopicContentLength(content);
		if(contentOK == 1){
			return;
		}
		if(contentOK == 2){
			return;
		}
		boolean contentC = FilterCharsUtil.containsFilterChars(content);
		if(contentC){
			return;
		}
		
		try {
			BbsUtil.updateForumFile(content, sample.getFilePath(), sample.getFileName(), sample.getFileExt(), uat);
		} catch (IOException e) {
			logger.error("Can not update forum topic : " + sample.getTopicId());
		}
		
		sample.setLastModifyTime(new Date());
		sample.setContent("");
		sample.setOriginal(topic.getOriginal());
		sample.setTitle(title);
		topicDao.save(sample);
		
	}
	/**
	 * 不减少积分
	 */
	public void deleteElite(Long topicId, Long userid) throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setElite(ConstantDB.UNELITE);
					topicDao.save(topic);
					userManager.reduceEliteAmount(topic.getUserid());
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not delete " + topicId + " elite");
		}
		
	}
	public void deleteTop(Long topicId, Long userid) throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setTop(ConstantDB.UNTOP);
					topicDao.save(topic);
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not delete " + topicId + " top");
		}
		
	}
	
	public void deleteCommend(Long topicId, Long userid)
			throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setCommend(ConstantDB.UNCOMMEND);
					topicDao.save(topic);
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not delete " + topicId + " commend");
		}
		
	}
	public void setCommend(Long topicId, Long userid)
			throws DataNotFoundException, AuthorityException {
		Topic topic = topicDao.get(topicId);
		List<Master> masters = masterManager.findMasterByTopicId(topicId);
		boolean tag = false;
		if(null != masters && masters.size() > 0){
			for(int i = 0; i < masters.size(); i ++){
				Master master = masters.get(i);
				if(userid.compareTo(master.getUserid()) == 0){
					topic.setCommend(ConstantDB.COMMEND);
					topic.setTop(ConstantDB.UNTOP);
					topic.setElite(ConstantDB.UNELITE);
					topicDao.save(topic);
					tag = true;
					break;
				}
			}
		}
		if(!tag){
			throw new AuthorityException("User : " + userid + " can not set " + topicId + " commend");
		}
	}

	/**
	 * 从缓存取得所有版区的前50个点击率最高的帖子，并且是当天发布的，
	 */
	public List<Topic> hotTopic(int amount) {
		List list = (List)CacheFactory.getInstance().getCache(Constants.CACHE_NAME_COMMON).get(Constants.CACHE_KEY_BBS_HOT_TOPIC_LIST);
		if(list != null && list.size() > 0){
			return list.subList(0, list.size() > amount ? amount:list.size()) ;
		}else{
			return new ArrayList<Topic>();
		}
	}
	/**
	 * 所有版区的前50个点击率最高的帖子，并且是当天发布的
	 */
	public List<Topic> initHotTopic(){
		PaginationSupport page = new PaginationSupport();
		page.setPageIndex(1);
		page.setPageSize(50);
		page.setClazz(Topic.class);		
		String queryString = " from Topic t where t.enabled=1 and t.createTime >= '" + DateUtil.getYear()+ "-" +DateUtil.getMonth()+ "-" +DateUtil.getDay()+ " 00:00:00' order by t.clickAmount desc";
		page.setQueryString(queryString);
		getPagination(page);
		return page.getItems();
		//CacheFactory.getInstance().getCache(Constants.CACHE_NAME_COMMON).put(Constants.CACHE_KEY_BBS_HOT_TOPIC_LIST, page.getItems());
	}
	
	/**
	 * 验证TOPIC TITLE
	 * @return 1:正常；2字符太少；3字符太多;4含有非法字符
	 */
	public int validateTopicTitle(String title){
		int titleOK = BbsUtil.checkTopicTitleLength(title);
		if(titleOK == 2){
			return 2;
		}
		if(titleOK == 3){
			return 3;
		}
		boolean titleC = FilterCharsUtil.containsFilterChars(title);
		if(titleC){
			return 4;
		}
		return 1;
	}
	
	/**
	 * 验证TOPIC content
	 * @return 1:正常；2字符太少；3字符太多;4含有非法字符
	 */
	public int validateTopicContent(String content){
		int titleOK = BbsUtil.checkTopicContentLength(content);
		if(titleOK == 2){
			return 2;
		}
		if(titleOK == 3){
			return 3;
		}
		boolean titleC = FilterCharsUtil.containsFilterChars(content);
		if(titleC){
			return 4;
		}
		return 1;
	}
}
